package org.light.facade;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.javaforever.gatescore.action.ParseSpreadSheetToProjectAction;
import org.javaforever.poitranslator.core.ProjectExcelWorkBook;
import org.light.domain.Project;
import org.light.domain.ValidateInfo;
import org.light.exception.ValidateException;
import org.light.utils.StringUtil;

import com.hmkcode.MultipartRequestHandler;
import com.hmkcode.vo.FileMeta;

import net.sf.json.JSONObject;

/**
 * 
 * @author Jerry Shen 2017/11/25
 *
 */
public class ExceltoProjectFacade extends HttpServlet {
	private static final long serialVersionUID = 147513641619203107L;
	
	private static List<FileMeta> files = new LinkedList<FileMeta>();

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ExceltoProjectFacade() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		processRequest(request, response);
	}
	
	protected String generateZip(String root, String filepath)
			throws Exception {
		InputStream is = null;
		POIFSFileSystem fs = null;
		Map<String, Object> result = new TreeMap<String, Object>();
		//request.setCharacterEncoding("UTF-8");
		File f2 =null;
		try {
		// deal with uploaded excel sheet
		String sourcefolder = root + "source/";
		f2 = new File(filepath);
		
		is = new FileInputStream(f2);
		fs = new POIFSFileSystem(is);
		HSSFWorkbook wb = new HSSFWorkbook(fs);
		ProjectExcelWorkBook pewb = new ProjectExcelWorkBook();
	
		Project project = pewb.translate(wb);
		project.setExcelTemplateName(f2.getName());
		project.setExcelTemplateFolder(root+"spreadsheets/");
	
		System.out.println(sourcefolder);
		project.setFolderPath(sourcefolder);
		if (project.getTechnicalstack() == null || "".equalsIgnoreCase(project.getTechnicalstack())
				|| "sbmeu".equalsIgnoreCase(project.getTechnicalstack())) {
			project.setSourceFolderPath(
					(root + "templates/").replace('\\', '/'));
			project.generateProjectZip();
	
			return project.getStandardName();
		}else {
			throw new ValidateException("技术栈设置错误！");
		}
		}catch (Exception e) {
			e.printStackTrace();
			if (e instanceof ValidateException) {
				throw e;
			}			
			return "";
		}finally {
			if (is!= null) {
				is.close();
				is = null;
			}
			if (fs != null){
				fs.close();
				fs = null;
			}
		}
	}

	protected void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException{
		InputStream input = null;
		OutputStream output = null;
		InputStream is = null;
		POIFSFileSystem fs = null;
		response.setContentType("text/plain;charset=UTF-8");
		PrintWriter out = response.getWriter();
		Map<String, Object> result = new TreeMap<String, Object>();
		//request.setCharacterEncoding("UTF-8");
		File f =null;
		try {
			// 1. Upload File Using Apache FileUpload
			files.addAll(MultipartRequestHandler.uploadByApacheFileUpload(request));

			String root = request.getSession().getServletContext().getRealPath("/").replace('\\', '/');;
			String excelfolder = root+ "spreadsheets/";
			excelfolder = excelfolder.replace('\\', '/');
			System.out.println("JerryDebug:excelfolder:"+excelfolder);
			
			String [] fileNames =  files.get(0).getFileName().replace('\\', '/').split("/");
			String fileName = "";
			if (fileNames.length > 0) fileName = fileNames[fileNames.length-1];
			else throw new ValidateException("文件上传出错");
			
			f = Project.createPathFile((excelfolder +fileName));
			
			input = files.get(0).getContent();
			if (f!=null) output = new FileOutputStream(f);
			else throw new ValidateException("创建文件失败！");
			byte[] buffer = new byte[1024 * 10];
			
			for (int length = 0; (length = input.read(buffer)) > 0;) {
				output.write(buffer, 0, length);
			}	
			
			files = new LinkedList<FileMeta>();
			// Generate source zip file
			String generatedFile = generateZip(root, f.getPath());	

			String frontZipName = ParseSpreadSheetToProjectAction.doParseExcel(excelfolder, fileName, root+"templates/", root+"source/",false,true);
			if (!StringUtil.isBlank(generatedFile)&&!StringUtil.isBlank(frontZipName)) {
				result.put("success", true);
				result.put("projectName",generatedFile);
				result.put("frontProjectName", frontZipName);
				out.print(JSONObject.fromObject(result));
			}else{
				throw new ValidateException("文件生成错误！");
			}			
		} catch (ValidateException ev) {
			result.put("success", false);
			ValidateInfo info = ev.getValidateInfo();
			List<String> compileErrors = info.getCompileErrors();
			result.put("compileErrors", compileErrors);
			List<String> compileWarnings = info.getCompileWarnings();
			result.put("compileWarnings", compileWarnings);
			out.print(JSONObject.fromObject(result));
		} catch (Exception e) {
			if (e instanceof ValidateException) {
				ValidateException ev = (ValidateException)e;
				result.put("success", false);
				ValidateInfo info = ev.getValidateInfo();
				List<String> compileErrors = info.getCompileErrors();
				result.put("compileErrors", compileErrors);
				List<String> compileWarnings = info.getCompileWarnings();
				result.put("compileWarnings", compileWarnings);
				out.print(JSONObject.fromObject(result));
				return;
			}
			if (!(e instanceof ValidateException)) {
				e.printStackTrace();
				result.put("success", false);
				if (e.getMessage() != null && !e.getMessage().equals("")) {
					result.put("compileErrors", new ArrayList<String>().add(e.getMessage()));
				} else {
					result.put("compileErrors", new ArrayList<String>().add("空指针或其他语法错误！"));
				}
				out.print(JSONObject.fromObject(result));
			}
		} finally {
			if (input!=null) input.close();
			if (output!=null) output.close();
			if (is!=null) is.close();
			if (fs!=null) fs.close();
			if (out!=null) out.close();
		}
	}
}
